package com.fingard.dsp.bank.directbank.icbc02;

import java.io.IOException;
import java.util.Date;
import java.util.HashMap;

import org.apache.commons.lang.StringEscapeUtils;

import com.alibaba.fastjson.JSONObject;
import com.fingard.constant.Format;
import com.fingard.dsp.bank.directbank.bankInterface.IOtherElse;
import com.fingard.dsp.bank.reqrespobj.otherelse.ReqOtherElse;
import com.fingard.dsp.bank.reqrespobj.otherelse.RetAtsOtherElse;
import com.fingard.text.StringHelper;

public class ICBC02OtherElse extends ICBC02Base implements IOtherElse{

	@Override
	public RetAtsOtherElse d_else(ReqOtherElse p_reqElse) throws Exception {
		 if ("PosQuery".equals(p_reqElse.reqHeader.transType)) {
				if ("PQ01".equals(p_reqElse.reqHeader.commandCode)) {
					return verifyPosQuery(p_reqElse);
				} else {
					return signPosQuery(p_reqElse);
				}
			} else if ("PosNotify".equals(p_reqElse.reqHeader.transType)) {
				if ("PS01".equals(p_reqElse.reqHeader.commandCode)) {
					return verifyPosNotify(p_reqElse);
				} else {
					return signPosNotify(p_reqElse);
				}
			} else {
				RetAtsOtherElse retAts = new RetAtsOtherElse(p_reqElse.reqHeader);
				
				retAts.retHashMap = new HashMap<String, String>();
				retAts.retHashMap.put("RespCode", "-1");
				retAts.retHashMap.put("RespInfo", "未知的TransType：" + p_reqElse.reqHeader.transType);
				
				return retAts;
			}
	}

	public RetAtsOtherElse verifyPosQuery(ReqOtherElse p_reqElse) {
		// TODO Auto-generated method stub
		RetAtsOtherElse retAts = new RetAtsOtherElse(p_reqElse.reqHeader);
		retAts.retHashMap = new HashMap<String, String>();
		try{
			String plain = "";
			if (p_reqElse.reqHashMap.containsKey("ReqMsg")) {
				plain = p_reqElse.reqHashMap.get("ReqMsg");
			} else {
				retAts.retHashMap.put("RespCode", "-1");
				retAts.retHashMap.put("RespInfo", "缺失'ReqMsg'!");
				return retAts;
			}
			String sign = plain.substring(85);
			WriteBankLogLn2("POS原始签名:" + sign);
			String signData = plain.substring(4, 85);
			String mac = getMac(signData.getBytes(getPOSCharset()));
			mac=str2HexStr(mac);
			WriteBankLogLn2("本机签名:" + mac);
			if (sign.equals(mac)) {
				String askNumber = plain.substring(47, 63).trim();
				String seqNoCheck = plain.substring(63, 71).trim();
				
				String refundFlag = "false";
				String transType = plain.substring(4, 8);
				if (!"0110".equals(transType)) {
					refundFlag = "true";
				} 
				
				JSONObject result = new JSONObject();
				result.put("Rdseq", askNumber);
				result.put("RdseqAuthCode", seqNoCheck);
				result.put("IsRefund", refundFlag);
				result.put("ReserveField", signData);
				
				retAts.retHashMap.put("RespCode", "0");
				retAts.retHashMap.put("RespInfo", "验签通过");
				retAts.retHashMap.put("Result", result.toJSONString());
			} else {
				retAts.retHashMap.put("RespCode", "-1");
				retAts.retHashMap.put("RespInfo", "验签失败!");
			}
			
		}
		catch(Exception ex){
			ex.printStackTrace();
			retAts.retHashMap.put("RespCode", "-1");
			retAts.retHashMap.put("RespInfo", ex.getMessage());
			WriteBankLogLn(ex);
		}

		return retAts;
	}
	public RetAtsOtherElse signPosQuery(ReqOtherElse p_reqElse) {
		RetAtsOtherElse retAts = new RetAtsOtherElse(p_reqElse.reqHeader);
		retAts.retHashMap = new HashMap<String, String>();
		try {
			String plain = "";
			if (p_reqElse.reqHashMap.containsKey("ReqMsg")) {
				plain = p_reqElse.reqHashMap.get("ReqMsg");
			} else {
				retAts.retHashMap.put("RespCode", "-1");
				retAts.retHashMap.put("RespInfo", "缺失原始串'ReqMsg'");
				return retAts;
			}
			JSONObject reqJson = JSONObject.parseObject(plain);
			StringBuilder sbContent = new StringBuilder();
			
			String reserveField = reqJson.getString("ReserveField");
			String transType = reserveField.substring(0, 4);
			if("0110".equals(transType)){
				transType="0111";
			}
			else{
				transType="0211";
			}
			
			sbContent.append(transType);// 交易类型
			sbContent.append(String.format("%-12s", reserveField.substring(4, 16)));// 银行代码
			sbContent.append(String.format("%-4s", reserveField.substring(16, 20)));//保险公司代码
			sbContent.append(String.format("%-15s", reserveField.substring(20, 35)));// 商户号
			sbContent.append(String.format("%-8s", reserveField.substring(35, 43)));// 终端号
			sbContent.append(String.format("%-16s", reserveField.substring(43, 59))); // 业务流水号
			sbContent.append(String.format("%-8s", reserveField.substring(59, 67)));// 业务流水校验码
			sbContent.append(String.format("%-12s", reqJson.getString("Amount")));//交易金额
			sbContent.append(Format.DateTime14Format.format(new Date())); // 交易时间(yymmddhhmmss)		
			sbContent.append(String.format(reqJson.getString("ReturnCode")));//交易成功标识
			String mac=getMac(sbContent.toString().getBytes(getPOSCharset()));
			mac=str2HexStr(mac);
			//sbContent.append(String.format("%-16s", mac));//mac校验码
			
			String result = String.format("%4s", sbContent.toString().getBytes("GBK").length + 16).replace(' ', '0') + sbContent.toString()+mac;
			
			retAts.retHashMap.put("RespCode", "0");
			retAts.retHashMap.put("RespInfo", "");
			retAts.retHashMap.put("Result", result);
			
		} catch (Exception ex) {
			// TODO: handle exception
			ex.printStackTrace();
			retAts.retHashMap.put("RespCode", "-1");
			retAts.retHashMap.put("RespInfo", ex.getMessage());
			WriteBankLogLn(ex);
		}

		return retAts;
	}
	public RetAtsOtherElse verifyPosNotify(ReqOtherElse p_reqElse) {
		RetAtsOtherElse retAts = new RetAtsOtherElse(p_reqElse.reqHeader);
		retAts.retHashMap = new HashMap<String, String>();
		try {
			String plain = "";
			if (p_reqElse.reqHashMap.containsKey("ReqMsg")) {
				plain = StringEscapeUtils.unescapeHtml(p_reqElse.reqHashMap.get("ReqMsg"));
			} else {
				retAts.retHashMap.put("RespCode", "-1");
				retAts.retHashMap.put("RespInfo", "缺失原始串'ReqMsg'");
				return retAts;
			}
			// 1、验签
			String sign = plain.substring(167);
			WriteBankLogLn2("POS原始签名:" + sign);
			String signData = plain.substring(4, 167);
			String mac = getMac(signData.getBytes(getPOSCharset()));
			mac=str2HexStr(mac);
			WriteBankLogLn2("本机签名:" + mac);
			if (sign.equals(mac)) {
				// 组装返回数据
				String askNumber = plain.substring(47, 63).trim();
				
				String refundFlag = "false";
				String transType = plain.substring(4, 8);
				if (!"0100".equals(transType)) {
					refundFlag = "true";
				} 
				
				JSONObject result = new JSONObject();
				result.put("Rdseq", askNumber);
				result.put("IsRefund", refundFlag);
				result.put("ReserveField", signData);
				result.put("PayState", "success");
				result.put("PayInfoCode", "S0000");
				result.put("PayInfo", "S0000-支付成功");
				result.put("Amount", plain.substring(71, 83).trim());
				result.put("PayType", plain.substring(166, 167).trim());
				result.put("Asknumber", plain.substring(102, 132).trim());
				result.put("Abstracts", plain.substring(102, 132).trim());
				result.put("PayMadeDate", plain.substring(132, 146).trim());			
				result.put("TerminalCode", plain.substring(39, 47).trim());//TerminalCode	终端号
				result.put("MerchantID", plain.substring(24, 39).trim());//MerchantID	商户号
				result.put("OppBankAccount", plain.substring(83, 102).trim());//付方账号
				result.put("OppBankCode", "");//付方银行
				result.put("Reserved01", "");
				result.put("Reserved02", "");
				
				retAts.retHashMap.put("RespCode", "0");
				retAts.retHashMap.put("RespInfo", "验签通过");
				retAts.retHashMap.put("Result", result.toJSONString());
			} else {
				retAts.retHashMap.put("RespCode", "-1");
				retAts.retHashMap.put("RespInfo", "验签失败!");
			}
		} catch (Exception ex) {
			// TODO: handle exception
			ex.printStackTrace();
			retAts.retHashMap.put("RespCode", "-1");
			retAts.retHashMap.put("RespInfo", ex.getMessage());
			WriteBankLogLn(ex);
		}

		return retAts;
	}
	public RetAtsOtherElse signPosNotify(ReqOtherElse p_reqElse) {
		RetAtsOtherElse retAts = new RetAtsOtherElse(p_reqElse.reqHeader);
		retAts.retHashMap = new HashMap<String, String>();
		try {
			String plain = "";
			if (p_reqElse.reqHashMap.containsKey("ReqMsg")) {
				plain = p_reqElse.reqHashMap.get("ReqMsg");
			} else {
				retAts.retHashMap.put("RespCode", "-1");
				retAts.retHashMap.put("RespInfo", "缺失原始串'ReqMsg'");
				return retAts;
			}
			JSONObject reqJson = JSONObject.parseObject(plain);
			
			StringBuilder sbContent = new StringBuilder();
			String reserveField = reqJson.getString("ReserveField");
			String tranType=reserveField.substring(0, 4);
			if("0100".equals(tranType)){
				tranType="0101";
			}
			else{
				tranType="0211";
			}
			sbContent.append(tranType);// 交易类型
			sbContent.append(reserveField.substring(4, 16));// 银行代码
			sbContent.append(reserveField.substring(16, 20));// 保险公司代码
			sbContent.append(reserveField.substring(20, 35));// 商户号
			sbContent.append(reserveField.substring(35, 43));// 终端号
			sbContent.append(reserveField.substring(43, 59)); // 业务流水号
			sbContent.append(reserveField.substring(59, 67));// 支付校验码
			sbContent.append(reserveField.substring(67, 79)); // 交易金额 以分为单位，左补零
			sbContent.append(reserveField.substring(79, 98)); // 缴费卡号
			sbContent.append(reserveField.substring(98, 128));// 银行流水号
			sbContent.append(reserveField.substring(128, 142)); // 交易时间(yymmddhhmmss)
			sbContent.append(reserveField.substring(142, 162));// 检索参考号
			sbContent.append(reqJson.getString("ReturnCode"));// 交易成功标识		
			
			String mac=getMac(sbContent.toString().getBytes(getPOSCharset())); // mac校验码
			mac=str2HexStr(mac);
			String result = String.format("%4s", sbContent.toString().getBytes("GBK").length + 16).replace(' ', '0') + sbContent.toString()+mac;
			
			retAts.retHashMap.put("RespCode", "0");
			retAts.retHashMap.put("RespInfo", p_reqElse.reqHashMap.get("ReturnMsg"));
			retAts.retHashMap.put("Result", result);
			
		} catch (Exception ex) {
			// TODO: handle exception
			ex.printStackTrace();
			retAts.retHashMap.put("RespCode", "-1");
			retAts.retHashMap.put("RespInfo", ex.getMessage());
			WriteBankLogLn(ex);
		}

		return retAts;
	}
	
	 /** 
     * mac计算,数据不为16的倍数，需要补0，将数据8个字节进行异或，再将异或的结果与下一个8个字节异或，一直到最后，将异或后的数据返回
     *  
     * @param Input 
     * @return 
     */  
	  public static byte[] clacMac(byte[] Input) {  
		  int length = Input.length;  
	        int x = length % 8;  
	        int addLen = 0;  
	        if (x != 0) {  
	            addLen = 8 - length % 8;  
	        }  
	        int pos = 0;  
	        byte[] data = new byte[length + addLen];  
	        System.arraycopy(Input, 0, data, 0, length);  
	        byte[] oper1 = new byte[8];  
	        System.arraycopy(data, pos, oper1, 0, 8);  
	        pos += 8;  
	        for (int i = 1; i < data.length / 8; i++) {  
	            byte[] oper2 = new byte[8];  
	            System.arraycopy(data, pos, oper2, 0, 8);  
	            byte[] t = bytesXOR(oper1, oper2);  
	            oper1 = t;  
	            pos += 8;  
	        }  
	        // 取8个长度字节  
	        byte[] retBuf = new byte[8];  
	        System.arraycopy(oper1, 0, retBuf, 0, 8);
	        return retBuf;
	    }  
    public static byte[] bytesXOR(byte[] src, byte[] src1) {  
        int length = src.length;  
        if (length != src1.length) {  
            return null;  
        }  
        byte[] result = new byte[length];  
        for (int i = 0; i < length; i++) {  
            result[i] = byteXOR(src[i], src1[i]);  
        }  
        return result;  
    }  
	public static byte byteXOR(byte src, byte src1) {  
        return (byte) ((src & 0xFF) ^ (src1 & 0xFF));  
    }  
	
	
    /**
     * 字符串转换成为16进制(无需Unicode编码)
     * @param str
     * @return
     */
    public static String str2HexStr(String str) {
        char[] chars = "0123456789ABCDEF".toCharArray();
        StringBuilder sb = new StringBuilder("");
        byte[] bs = str.getBytes();
        int bit;
        for (int i = 0; i < bs.length; i++) {
            bit = (bs[i] & 0x0f0) >> 4;
            sb.append(chars[bit]);
            bit = bs[i] & 0x0f;
            sb.append(chars[bit]);
            // sb.append(' ');
        }
        return sb.toString().trim();
    }
	public static String getMac(byte[] Input) throws IOException {
        return new String(clacMac(Input), "GBK");
	}
}
